<template>
  <div>
    <!--上半部分-->
    <div class="comment-area">
      <!-- 左侧的头像 -->
      <div class="comment-avatar">
        <!--评论区头像 未登录 默认头像-->
        <div v-if="!$store.state.userInfo" class="bili-avatar" style="width: 40px;height: 40px;"></div>
        <div v-else class="bili-user-avatar">
          <img :src="$util.url.load + $store.state.userInfo.avatar" style="width: 40px;height: 40px;" alt="">
        </div>
      </div>
      <!-- 文本框 和 评论按钮 -->
      <div :class="['comment-right', { height80: height80 }]">
        <!-- 文本框 -->
        <textarea v-if="$store.state.userInfo" :disabled="this.$store.state.userInfo?false:true" id="textarea" ref="textarea" class="edit-area" v-model="textareaContent" @focus="doFocus" @blur="doBlur"
                  :placeholder="placeholder" >
        </textarea>
        <div class="reply-box-wrap" v-else>
          <div class="no-login-mask" @click="$store.commit('changeLogView')">
            <span class="no-login-span">请先</span>
            <span class="no-login-btn">登录</span>
            <span class="no-login-span">后发表评论 (・ω・)</span>
          </div>
        </div>
        <!-- 评论按钮 -->
        <div :disabled="this.$store.state.userInfo?false:true" :class="['comment-btn',$store.state.userInfo ? 'send-text' : 'no-login-send-text']" @click="postComment">发布</div>
      </div>
    </div>

    <!--下半部分-->
    <div v-show="emojiSpark">
      <div class="comment-tips">
        <!-- 触发 表情icon -->
        <span @click="activeEmojiPanel($event, true)"
              :class="['emojiSparkDefault','iconfont icon-a-biaoqing24', { active: emojiPanelActive }]">
        </span>
        <!--@ 艾特符号-->
        <span style="margin-left: 10px" class="iconfont icon-aite emojiSparkDefault"></span>
      </div>
      <!-- 待选择的表情列表 -->
      <div class="emoji-wrapper-relative" @click="activeEmojiPanel" v-show="emojiPanelActive">
          <!--表情名称-->
          <div class="emoji-wrapper-top">
            <span>{{ typeName }}</span>
          </div>
          <!--表情列表-->
          <div class="emoji-wrapper scaleUp">
              <span @click="addEmoji(emoji)" class="emoji" v-for="(emoji,index) in emojiList" :key="index">
                  <img :src="emoji.link" alt="">
              </span>
          </div>
          <!--表情切换按钮-->
          <div class="emoji-wrapper-bottom">
            <ul class="emojiMenuUl">
              <li v-for="(item,index) in emojiMenuUlList" :key="index" @click="changeMenuLibg(index)"
                  :class="['iconfont emojiMenuLi',item.type,{ emojiMenuLibg : item.emojiTypebg ,emojiMenuLiHover : !item.emojiTypebg}]"></li>
            </ul>
          </div>
          <!-- 三角形 -->
          <div v-show="emojiPanelActive" class="triangle"></div>
        </div>
    </div>
  </div>
</template>


<script>

export default {
  name: "EmojiText",
  props: {
    closeReplay:{
      type:Boolean,
      default:false
    },
    commentListItem:{
      type:Object
    },
    imgPrefix: { /* 图片路径前缀 */
      type:String,
      default:''
    },
    placeholder: { /* 默认占位符 */
      type:String,
      default: '快快来发表你的观点吧~~'
    },
    avatarUrl: { /* 头像 */
      type:String
    },
    emojiSize:{
      type:Number,
      default: null
    },
    afterComment: {  /* 发表评论之后，需要执行的函数 */
      type: Function
    }
  },
  data(){
    return{
      // 表情类型名
      typeName:'小黄脸',
      // 表情切换按钮List
      emojiMenuUlList:[
        {
          "typeId":1,
          "typeName":"小黄脸",
          "type":"icon-huoyan-biaoqing1",
          "emojiTypebg":false
        },
        {
          "typeId":2,
          "typeName":"tv_小电视",
          "type":"icon-jiazaishibai",
          "emojiTypebg":false
        },
        {
          "typeId":3,
          "typeName":"原神",
          "type":"icon-a-biaoqing24",
          "emojiTypebg":false
        },
        {
          "typeId":4,
          "typeName":"颜文字",
          "type":"icon-biaoqing",
          "emojiTypebg":false
        }
      ],
      // 表情弹框 触发器
      emojiSpark:false,
      /* 文本框中有文字 或 无文字但是处于焦点状态时 为true */
      height80: false,
      /* 表情配置数据 */
      emojiList:[],
      /* 是否打开表情面板 */
      emojiPanelActive: false,
      /* 文本框的内容 */
      textareaContent: '',

    }
  },
  created() {

  },
  mounted() {
    let _this = this
    document.addEventListener('click', function () { /* 点击其它地方, 关闭表情面板 */
      _this.emojiPanelActive = false
      //console.log("点击其它地方, 关闭表情面板",e)
    })
  },
  methods: {

    // 改变表情切换按钮(index 数组下标) 颜色样式
    changeMenuLibg(index){
      /*由于 JavaScript 的限制，Vue 不能检测以下变动的数组：
      当你利用索引直接设置一个项时，例如：vm.items[indexOfItem] = newValue
      当你修改数组的长度时，例如：vm.items.length = newLength
      具体原因是因为Vue2中发布订阅模式使用的是Object.defineProperty()方法来监听数据的改变，而这个方法的缺陷就是无法监听数据变动，在Vue3中已经用Proxy代替改方法，并解决该问题。`
      解决:
      根据vue的官方文档说明：Vue 包含一组观察数组的变异方法，所以它们将会触发视图更新。 这些方法如下：push() pop() shift() unshift() splice() sort() reverse()
      所以当我们想要页面实时更新的话就必须使用以上方法。*/
      for (let i = 0; i < this.emojiMenuUlList.length; i++) {
        if (i === index){
          let item = {}
          item.type = this.emojiMenuUlList[i].type
          item.typeName = this.emojiMenuUlList[i].typeName
          item.emojiTypebg = true
          this.emojiMenuUlList.splice(i,1,item)
          // this.emojiMenuUlList[index].emojiTypebg = true
          this.typeName = this.emojiMenuUlList[i].typeName
          // 更换表情包
          this.getEmojiList(i+1)
        }else {
          // this.emojiMenuUlList[index].emojiTypebg = false
          let item = {}
          item.type = this.emojiMenuUlList[i].type
          item.typeName = this.emojiMenuUlList[i].typeName
          item.emojiTypebg = false
          this.emojiMenuUlList.splice(i,1,item)
        }
      }
    },
    // 获取仓库表情包数据 index 是typeId
    getEmojiList(index){
      let list = this.$store.state.emojiList.filter(item => item.type == index)
      if (list == undefined ||list == null || list.length <= 0) return
      this.emojiList = list
    },
    /* 添加表情 */
    addEmoji(emoji) {
      let textarea = this.$refs['textarea'];
      if (textarea === null || textarea === undefined) return
      // selectionStart和 selectionEnd的值由光标所在的位置决定
      console.log(textarea.selectionStart, textarea.selectionEnd, 'start,end');

      // 最开始的位置要记录下，后面要根据它来设置插入文本后，设置光标的位置
      let selectionStart1 = textarea.selectionStart

      let txtArr = this.textareaContent.split('')
      txtArr.splice(textarea.selectionStart, textarea.selectionEnd - textarea.selectionStart, emoji.title)
      this.textareaContent = txtArr.join('')

      /* 一定要放在$nextTick去执行, 上面修改完值后, 还要等vue把修改的数据渲染出来之后, 再去定位光标 */
      this.$nextTick(() => {
        // 替换文本后, 需要把光标，再次定位到替换后的那个位置，否则，它会回到最前面
        textarea.focus()
        textarea.setSelectionRange(selectionStart1 + emoji.title.length, selectionStart1 + emoji.title.length)
      })
    },

    /* 激活表情面板, 第二个参数: 是否切换 */
    activeEmojiPanel(e, isToggle) {
      if (isToggle) {
        this.emojiPanelActive = !this.emojiPanelActive
      } else {
        this.emojiPanelActive = true
      }
      e.stopPropagation() /* 阻止事件冒泡 */
    },
    /* 文本域获得焦点时 */
    doFocus(){
      // 加载表情切换按钮
      this.changeMenuLibg(0)
      this.height80 = true
      this.emojiSpark = true
    },
    /* 文本域失去焦点时 */
    doBlur() {
      if (this.textareaContent.length > 0) {
        this.height80 = true
        this.emojiSpark = true
      } else {
        this.height80 = false
      }
    },

    /* 发表评论 */
    postComment() {
      if(!this.textareaContent) {
        return
      }
      let _this = this
      /* 处理换行, 虽然解决了, 但是不知道为什么在文本域里面按enter和手动输入\n有啥区别?
         哦懂了, \n在正则里面就是表示的换行这一个字符, 手动输入的\n其实是2个字符, 按enter输入的其实是一个字符（虽然它看上去是2个字符）,
         我们程序员习惯了\n表示换行这个字符(但这只是在开发工具里面支持的写法),
         如果把下面改成 /\\n/ 去替换那就可以匹配到手动输入的\n这2个字符
      */
      // console.log(this.textareaContent,'textareaContent');
      let result = this.textareaContent.replace(/\n/g, function (str) {
        console.log('检测到str:' + str);
        return "<br/>"
      })
      // console.log(result,'result');

      /* 处理表情 */
      /* 这个replace函数, 第一个参数是正则表达式, 他回去匹配文本；第二个参数是将匹配的文本传入进行处理的函数，函数的返回值将会替换匹配的文本 */
      result = result.replace(/\[.*?]/g, function (str) {// str为匹配到的值，如 [大笑]
        //console.log("str==",str)
        // 获取存储在仓库的表情数据
        let link = _this.$store.state.emojiList.filter(item => item.title == str)
        if(link){
          if(_this.emojiSize) {
            return `<img src="${_this.imgPrefix}${link[0].link}" style="width:${_this.emojiSize}px;height:${_this.emojiSize}px;"/>`;
          } else {
            return `<img src="${_this.imgPrefix}${link[0].link}" />`;
          }
        }
      })
      //console.log("postComment(最终内容修改为)",result)
      // 子传父值 将内容传给父组件
      this.$emit('comment',result,_this.commentListItem)
      this.textareaContent = ''
      this.doBlur()
      this.afterComment && this.afterComment()
    }
  },


}
</script>

<style scoped>


.edit-area::-webkit-scrollbar {
  border-radius: 5px;
  width: 4px;
}
.edit-area::-webkit-scrollbar-thumb {
  border-radius: 5px;
  background-color: #d9d9d9;
}

textarea {
  outline: none;
  border: none;
  background: #f1f2f3;
  resize: none;
  border-radius: 8px;
  padding: 10px 10px;
  font-size: 16px;
  color: #333333;
  border: 1px solid transparent;
}
img {
  -webkit-user-drag: none;
}
.avatar {
  width: 40px;
  height: 40px;
  object-fit: cover;
}

.height80 {
  height: 70px !important;
}

.height80 textarea {
  border: 1px solid #49b1f5;
}

@keyframes scaleUp {
  0% {
    opacity: 0;
    transform: scale(0)
  }
  100% {
    opacity: 1;
    transform: scale(1)
  }
}

.scaleUp {
  animation: scaleUp 0.3s;
  transform-origin: 0 0;
}
.comment-area {
  display: flex;
  align-items: flex-start;
  /*margin-bottom: 24px;*/

  color: #90949e;
}
#textarea:hover{
  border: 1px solid rgb(201,204,208);
  background-color: white;
}
.comment-avatar {
  width: 48px;
  height: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 18px;
}
.bili-avatar {
  display: block;
  position: relative;
  background-image: url();
  background-size: cover;
  border-radius: 50%;
}

.bili-user-avatar {
  display: block;
  position: relative;
  background-size: cover;
  /* background-color: transparent; */
  border-radius: 50%;
  overflow: hidden;
  height: 40px;
  width: 40px;
}
.comment-avatar i {
  font-size: 40px;
  border: 1px solid #c4c4c4;
  border-radius: 50%;
}
.comment-right {
  flex: 1;
  display: flex;
  height: 50px;
  transition: height 0.5s;
  position: relative;
}
.edit-area {
  line-height: 27px;
  font-size: 13px;
  flex: 1;
}
.reply-box-wrap {
  position: relative;
  flex: 1;
}
.no-login-mask {
  display: flex;
  justify-content: center;
  align-items: center;
  position: absolute;
  top: 0;
  left: 0;
  z-index: 1;
  width: 100%;
  height: 100%;
  border-radius: 5px;
  font-size: 12px;
  background-color: rgb(241, 242, 243);
  cursor: pointer;
}

.no-login-span {
  padding-left: 5px;
  padding-right: 5px;
}


.no-login-btn {
  padding: 4px 9px;
  border-radius: 4px;
  color: white;
  background: rgb(0, 174, 236);
}

.no-login-btn:hover {
  background-color: rgb(64, 197, 241);
}
.send-text {
  background-color: rgb(127,214,245);
  color: #fff;
}
.send-text:hover{
  background-color: rgb(0,174,236);
}
.no-login-send-text {
  background-color: rgb(241, 242, 243);
  color: rgb(148, 153, 160);
}
.comment-btn {
  cursor: pointer;
  width: 64px;
  border-radius: 5px;
  margin-left: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.comment-tips {
  margin-left: 82px;
  padding: 3px 0 0 0;
  /*display: block;*/
  /*position: absolute;*/
  /*bottom: -28px;*/
  height: 24px;
  /*width: calc(100% - 72px);*/
  /*margin-right: 72px;*/
  /*display: flex;*/
  align-items: center;
  line-height: 24px;
}
.emojiSparkDefault {
  color: rgb(148, 153, 160);
}
.active {
   color: #49b1f5;
 }


.emoji-wrapper-relative {
/*  有时候我们需要在父元素的容器内设置相对的绝对位置
  要做到这一点需要把父元素的position属性设置为relative，
  设置为relative之后不设置left和top属性，这时候父元素虽然是relative的，但是还是在原来位置。*/
  position: relative;
}
.emoji-wrapper-top{
  z-index: 3;
  position:absolute;
  top:5px;
  left: 80px;
  height: 30px;
  width: 294px;
  line-height: 30px;
  color: rgb(97,102,109);
  font-size:13px;
  border-top-left-radius: 6px;
  border-top-right-radius: 6px;

  background-color: #fff;
  box-shadow: 0 3px 6px 0 rgb(0 0 0 / 12%);
  border-top:1px solid rgba(0, 0, 0, .06);
  border-left: 1px solid rgba(0, 0, 0, .06);
  border-right: 1px solid rgba(0, 0, 0, .06);

}
.emoji-wrapper-top span{
  margin-left: 10px;
}
.emoji-wrapper {
  z-index: 3;
  user-select: none;
  position: absolute;
  bottom: 0;
  top: 35px;
  left: 80px;
  display: flex;
  flex-wrap: wrap;
  width: 294px;
  height: 200px;
  overflow-y: auto;

  background-color: #fff;
  padding: 5px;
  box-shadow: 0 3px 6px 0 rgb(0 0 0 / 12%);
  border-left: 1px solid rgba(0, 0, 0, .06);
  border-right: 1px solid rgba(0, 0, 0, .06);
}
.emoji-wrapper-bottom{
  z-index: 3;
  position:absolute;
  top:235px;
  left: 80px;
  height: 30px;
  width: 294px;
  line-height: 30px;
  color: rgb(97,102,109);
  font-size:13px;
  border-bottom-left-radius: 6px;
  border-bottom-right-radius: 6px;

  background-color: #fff;
  box-shadow: 0 3px 6px 0 rgb(0 0 0 / 12%);
  border-bottom:1px solid rgba(0, 0, 0, .06);
  border-left: 1px solid rgba(0, 0, 0, .06);
  border-right: 1px solid rgba(0, 0, 0, .06);
}
.emojiMenuUl{
  list-style-type: none;
  margin: 0;
  padding: 0;
}
.emojiMenuLi{
  display: inline-block;
  width: 50px;
  background-color: rgb(241,242,243);
  text-align: center;
  cursor: pointer;
}
.emojiMenuLibg{
  background-color: rgb(255,255,255);
}
.emojiMenuLiHover:hover{
  background-color: rgb(227,229,231);
}
.emoji-wrapper::-webkit-scrollbar {
  border-radius: 4px;
  width: 4px;
}
.emoji-wrapper::-webkit-scrollbar-thumb {
  border-radius: 4px;
  background-color: #d9d9d9;
}
.emoji-wrapper::before {
  content: '';
  position: absolute;
}
.emoji {
  width: 30px;
  height: 30px;
  display: block;
  margin: 2px;
  cursor: pointer;
  padding: 3px;
  border-radius: 6px;
  transition: all 0.28s;
}
.emoji:hover {
  background-color: #dddddd;
}
.emoji img {
  width: 100%;
  height: 100%;
}
.triangle {
  content: '';
  position: absolute;
  width: 8px;
  height: 8px;
  top: 2px;
  left: 86px;
  background-color: white;
  border: 1px solid #f0f0f0;
  transform: rotate(45deg);
  border-right-color: transparent;
  border-bottom-color: transparent;
}

</style>
